# todo  这是笔记的视图
import datetime

from flask import request
from marshmallow import ValidationError

from utils import ThreadLocal
from common.ApiResponse import ApiResponse
from common.ErrorCode import ErrorCode
from common.BaseResponse import BaseResponse
from models import db, Article, Category
from .validate import AddArticleSchema, UpdateArticleSchema, ListArticleSchema

add_article_schema = AddArticleSchema()
update_article_schema = UpdateArticleSchema()
list_article_schema = ListArticleSchema()


# todo 文章添加视图
def add():
    data = request.json
    try:
        add_article_schema.load(data)
    except ValidationError as e:
        # 参数校验
        error_response = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
        first_key, first_value = next(iter(e.messages.items()))
        return ApiResponse.error(message=error_response.message, code=error_response.code,data=first_value[0])
    try:
        article = Article(
            title=data['title'],
            content=data['content'],
            cover_img=data['coverImg'],
            state=data['state'],
            category_id=data['categoryId'],
            create_user=ThreadLocal.ThreadLocalUtil.get().get('id'),
        )
        db.session.add(article)
        db.session.commit()
        return ApiResponse.success("添加成功!")
    except Exception as e:
        print(f"添加报错：{e}")
        db.session.rollback()
        error_response = BaseResponse.from_error_code(ErrorCode.OPERATION_ERROR)
        return ApiResponse.error(data=error_response.message, code=error_response.code)


# todo 这是文章列表视图
def article_list():
    data = request.args
    try:
        validation = list_article_schema.load(data)
    except ValidationError as e:
        print("validation")
        error_response = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
        first_key, first_value = next(iter(e.messages.items()))
        return ApiResponse.error(message=error_response.message, code=error_response.code, data=first_value[0])
    page_num = data.get('pageNum')
    page_num = int(page_num)
    page_size = data.get('pageSize')
    page_size = int(page_size)
    category_id = data.get('categoryId')
    state = data.get('state')
    create_user = ThreadLocal.ThreadLocalUtil.get().get('id')
    try:
        query = db.session.query(Article)
        if category_id:
            query = query.filter(Article.category_id == category_id)

        if state:
            query = query.filter(Article.state == state)

        query = query.filter(Article.create_user == create_user)
        total = query.count()
        articles = query.offset((page_num - 1) * page_size).limit(page_size).all()
        items = []
        for article in articles:
            category_id = article.category_id
            category = db.session.query(Category).filter(Category.id == category_id).first()
            items.append({
                "id": article.id,
                "title": article.title,
                "content": article.content,
                "coverImg": article.cover_img,
                "state": article.state,
                "categoryId": category_id,
                "createTime": article.create_time.strftime("%Y-%m-%d %H:%M:%S"),
                "updateTime": article.update_time.strftime("%Y-%m-%d %H:%M:%S"),
                "categoryName": category.category_name,
            })
        data = {
            "total": total,
            "items": items
        }
        return ApiResponse.success(data=data)
    except Exception as e:
        db.session.rollback()
        error_response = BaseResponse.from_error_code(ErrorCode.OPERATION_ERROR)
        return ApiResponse.error(code=error_response.code, message=error_response.message)


# todo 这是文章更新视图
def update():
    data = request.json
    try:
        error = update_article_schema.load(data)
    except ValidationError as e:
        error_response = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
        first_key, first_value = next(iter(e.messages.items()))
        return ApiResponse.error(message=error_response.message, code=error_response.code, data=first_value[0])
    try:
        articles = db.session.query(Article).filter(Article.id == data['id']).first()
        articles.id = data['id']
        articles.title = data['title']
        articles.content = data['content']
        articles.cover_img = data['coverImg']
        articles.state = data['state']
        articles.category_id = data['categoryId']
        articles.create_user = ThreadLocal.ThreadLocalUtil.get().get('id')
        articles.update_time = datetime.datetime.now()
        db.session.commit()
        return ApiResponse.success(data="更新成功")
    except Exception as e:
        db.session.rollback()
        error_response = BaseResponse.from_error_code(ErrorCode.OPERATION_ERROR)
        return ApiResponse.error(code=error_response.code, message=error_response.message)


# todo 这是文章详情视图
def detail():
    article_id = request.args.get("id")
    try:
        article = db.session.query(Article).filter(Article.id == article_id).first()
        data = {
            "id": article.id,
            "title": article.title,
            "content": article.content,
            "coverImg": article.cover_img,
            "state": article.state,
            "categoryId": article.category_id,
            "createUser": article.create_user,
            "createTime": article.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "updateTime": article.update_time.strftime("%Y-%m-%d %H:%M:%S"),
        }
        return ApiResponse.success(data=data)
    except Exception as e:
        db.session.rollback()
        error_response = BaseResponse.from_error_code(ErrorCode.OPERATION_ERROR)
        return ApiResponse.error(code=error_response.code, message=error_response.message)


# todo 这是删除文章视图
def delete():
    article_id = request.args.get("id")
    try:
        article = db.session.query(Article).filter(Article.id == article_id).first()
        db.session.delete(article)
        db.session.commit()
        return ApiResponse.success("删除成功！")
    except Exception as e:
        db.session.rollback()
        error_response = BaseResponse.from_error_code(ErrorCode.OPERATION_ERROR)
        return ApiResponse.error(code=error_response.code, message=error_response.message)
